/* 
 * Die Klasse Datenbank enthaelt saemtliche Daten des Projekts. Sie wird
 * zum Speichern und Laden von Datenstrukturen benutzt.
 * 
 * Datei: Datenbank.java      Autor:  Christian Plappert
 * Datum: 19.12.2011          Version: 0.4
 * 
 * Historie: 
 * 
 * 19.12.2011:  v0.4    Serialisierung von mit Hilfe von "basis" 
 *                      implementiert.
 * 08.12.2011:  v0.3    Integration der Medienverwaltung
 * 27.11.2011:  v0.2    Funktion gibFigur(...) implementiert, die 
 *                      Zugriff auf Standort ermoeglicht.
 * 22.11.2011:  v0.1    Klasse wurde angelegt und einige wichtige 
 *                      Listen integriert.                
 */

package bibvis;

import java.io.IOException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.swing.JOptionPane;

import GUI.Dashboard;
import basis.ea.EA;
import basis.lokal.Lokalisierung;
import basis.lokal.Sprachen;

import medienverwaltung.Regal;
import medienverwaltung.Standortverwalter;

public class Datenbank
{
  private HashMap<String, StandortDaten> standortListe;

  /* Klassenfelder */
  private Sprachwahl sprachwahl;
  private Standortverwalter standort;


  public Datenbank ()
  {
    /*
     * einmal sorgt dafuer, dass nicht zwei Fehlermeldungen erscheinen,
     * falls die erste ausgeloest wird.
     */
    boolean einmal;
    Sprachen sprache;
    Lokalisierung lokal;

    standortListe = new HashMap<String, StandortDaten> ();
    standort = new Standortverwalter ();

    sprache = Dashboard.verwendeteSprache ();
    setzeSprachwahl (new Sprachwahl (sprache.toString ()));
    lokal = gibSprachwahl ().lokal;
    einmal = true;
    try
    {
      DatenEinlesen ();
    }
    catch (Exception e)
    {
      einmal = false;
      JOptionPane.showMessageDialog (null,
          lokal.gibUebersetzung ("Keine Daten zum Laden gefunden."));
    }
    if (standortListe.isEmpty () && einmal)
    {
      JOptionPane.showMessageDialog (null,
          lokal.gibUebersetzung ("Keine Daten zum Laden gefunden."));
    }
  }


  /**
   * Falls bereits Daten vorhanden sind, werden diese hier eingelesen.
   * 
   * @warning In der Methode sind Warnungen vorhanden, die nicht
   *          entfernt werden koennen, da der Typ zur Laufzeit nicht
   *          ueberprueft werden kann.
   */
  private void DatenEinlesen ()
  {
    EA ea;

    ea = new EA ("bibvis.standort");
    standortListe = (HashMap<String, StandortDaten>) ea.einlesenXML ();
  }


  protected Sprachwahl gibSprachwahl ()
  {
    return sprachwahl;
  }


  protected void setzeSprachwahl (Sprachwahl sprachwahl)
  {
    this.sprachwahl = sprachwahl;
  }


  protected Standortverwalter gibStandort ()
  {
    return standort;
  }


  /**
   * Beschreibung: Speichert die Bibliothek in den peristenten Listen.
   * Sollten diese temporaere Listen enthalten, werden Kopien
   * gespeichert, da diese sonst geloescht werden koennten.
   * 
   * @param standort
   */
  protected void speichereBibliothek (String standort, 
    StandortDaten std)
  {
    EA ea;

    gibStandort ().speichern ();

    standortListe.put (standort, std);

    try
    {
      ea = new EA ("bibvis.standort");
      ea.speichernXML (standortListe);
    }
    catch (IOException e)
    {
      e.printStackTrace ();
    }
  }


  /**
   * Durchlaeuft die Standortliste und gibt alle Standorte aus, die
   * darin gespeichert sind.
   * 
   * @return Array mit allen gespeicherten Standorten
   */
  protected String[] gibVorhandeneBibliotheken ()
  {
    String[] temp = new String[standortListe.size ()];
    int i = 0;
    for (Map.Entry<String, StandortDaten> e : standortListe.entrySet ())
    {
      temp[i] = e.getKey ();
      i++;
    }

    return temp;
  }


  /**
   * Beschreibung: Laedt die gewaehlte Bibliothek anhand des Standorts
   * und loescht vorhandene temporaere Listen und fuellt sie dann
   * entsprechend der zu ladenden Bibliothek.
   * 
   * @param standort
   */
  protected StandortDaten ladeBibliothek (String standort)
  {
    for (Entry<String, StandortDaten> e : standortListe.entrySet ())
    {
      if (e.getKey ().equals (standort))
      {
        return e.getValue ();
      }
    }
    return null;
  }


  /**
   * Beschreibung: Loescht die gewaehlte Bibliothek anhand des
   * Standorts.
   * 
   * @param standort
   */
  protected void loescheBibliothek (String standort)
  {
    StandortDaten temp;
    int ids;
    EA ea;

    temp = null;
    for (Entry<String, StandortDaten> e : standortListe.entrySet ())
    {
      if (e.getKey ().equals (standort))
      {
        temp = e.getValue ();
      }
    }
    standortListe.remove (standort);
    ids = temp.gibZuordnungSI ().get (standort);
    gibStandort ().standortLoeschen (ids);

    try
    {
      ea = new EA ("bibvis.standort");
      ea.speichernXML (standortListe);
    }
    catch (IOException e)
    {
      e.printStackTrace ();
    }
  }


  protected HashMap<String, StandortDaten> gibStandortListe ()
  {
    return standortListe;
  }


  protected int[] gibStandortDaten (String standort)
  {
    return standortListe.get (standort).gibDimensionen ();
  }


  protected boolean standortVorhanden (String standort)
  {
    return standortListe.containsKey (standort);
  }


  /**
   * Wichtig fuer Schnittstelle
   * 
   * @see FassadeBibVis#zeigeStandort(String, int, int, int)
   * @param standort
   * @return
   */
  protected ArrayList<FigurZustand> gibRechtecke (String standort)
  {
    Iterator<Regal> it;
    ArrayList<Regal> regale;
    ArrayList<FigurZustand> rechtecke;

    regale = standortListe.get (standort).gibRegalListe ();
    HashMap<Regal, FigurZustand> zuordnungRZ = 
	standortListe.get (standort).gibZuordnungRZ ();
    rechtecke = new ArrayList<FigurZustand> ();

    for (it = regale.iterator (); it.hasNext ();)
    {
      rechtecke.add (zuordnungRZ.get (it.next ()));
    }
    return rechtecke;
  }


  /**
   * Wichtig fuer Schnittstelle
   * 
   * @see FassadeBibVis#zeigeStandort(String, int, int, int)
   * @param standort
   * @return
   */
  protected HashMap<ObjektAufzaehlung, ArrayList<FigurZustand>> 
    gibObjekte (String standort)
  {
    HashMap<ObjektAufzaehlung, ArrayList<FigurZustand>> objekte;

    objekte = standortListe.get (standort).gibObjektListe ();

    return objekte;
  }


  /**
   * Beschreibung: Gibt das zu markierende Rechteck zurueck.
   * 
   * @see FassadeBibVis#zeigeStandort(String, int, int, int)
   * @param standort
   * @param regalID
   * @return Regal
   */
  protected FigurZustand gibFigur (String standort, int regalID)
  {
    int i = 0;
    ArrayList<Regal> temp = (standortListe.get (standort))
        .gibRegalListe ();
    HashMap<Regal, FigurZustand> zuordnungRZ = 
      standortListe.get (standort).gibZuordnungRZ ();
    /*
     * Suche solange bis die RegalID eines Regals in der zu
     * durchlaufenden Liste mit der gesuchten uebereinstimmt
     */
    try
    {
      while ( (temp.get (i)).gibRegalId () != regalID)
      {
        i++;
      }

      return zuordnungRZ.get (temp.get (i));
    }
    catch (IndexOutOfBoundsException ioobex)
    {
      return null;
    }

  }


  protected Regal gibRegal (int regalID, String standort)
  {
    Regal gesuchtesRegal;
    ArrayList<Regal> regalListe;
    regalListe = standortListe.get (standort).gibRegalListe ();
    gesuchtesRegal = null;
    for (Regal regal : regalListe)
    {
      if (regal.gibRegalId () == regalID)
      {
        gesuchtesRegal = regal;
        break;
      }
    }
    return gesuchtesRegal;
  }


  protected int gibMassstab (String standort)
  {
    return standortListe.get (standort).gibMASSSTAB ();
  }

  /*
   * Debug-Methode
   */
  // protected void listenAusgeben ()
  // {
  // System.out
  // .println
  // ("\n--------------------MEDIENVERWALTUNG------------------\n");
  //
  // System.out.println ("\nStandortListeTemp:\n"
  // + standort.gibStandortListeTemp ());
  // System.out.println ("\nStandortListe:\n"
  // + standort.gibStandortListe ());
  // System.out.println ("\nStandortListeTemp2:\n");
  // standort.ausgabeStandortTemp ();
  // System.out.println ("\nStandortListe2:\n");
  // standort.ausgabeStandort ();
  // }

}
